<template>
	<div class="system-oss-container layout-pd">
		<el-card shadow="hover">
			<div class="system-oss-search mb15">
				<el-row :gutter="20">
					<el-col :span="24" v-auth="'system:oss:query'" class="col-center">
						<el-input size="default" placeholder="文件名查询" class="mt10" v-model="state.tableData.param.fileName"
							clearable @keyup.enter.native="getTableData" />
						<el-input size="default" placeholder="原名查询" class="mt10" v-model="state.tableData.param.bucketName"
							clearable @keyup.enter.native="getTableData" />
						<el-input size="default" placeholder="文件后缀" class="mt10" v-model="state.tableData.param.fileSuffix"
							clearable @keyup.enter.native="getTableData" />
						<el-input size="default" placeholder="上传人" class="mt10" v-model="state.tableData.param.createBy"
							clearable @keyup.enter.native="getTableData" />
						<el-input size="default" placeholder="服务商" class="mt10" v-model="state.tableData.param.service"
							clearable @keyup.enter.native="getTableData" />
						<el-date-picker v-model="state.dateRange" value-format="YYYY-MM-DD HH:mm:ss" type="daterange" @change="getTableData"
							range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" size="default" class="mt10"
							style="max-width: 200px;" />
						<el-button size="default" type="primary" class="mt10" @click="getTableData">
							<el-icon>
								<ele-Search />
							</el-icon>
							查询
						</el-button>
						<el-button size="default" class="mt10" type="info" @click="resetParamData()">
							<el-icon>
								<ele-Refresh />
							</el-icon>
							重置
						</el-button>
					</el-col>
					<el-col :span="24">
						<el-button size="default" type="success" class="mt10" @click="handleFile()"
							v-auth="'system:oss:upload'">
							<el-icon><ele-UploadFilled /></el-icon>
							上传文件
						</el-button>
						<el-button size="default" type="success" class="mt10" @click="handleImage()"
							v-auth="'system:oss:upload'">
							<el-icon><ele-PictureFilled /></el-icon>
							上传图片
						</el-button>
						<el-button size="default" type="danger" class="mt10" @click="handleDeletes()"
							v-auth="'system:oss:remove'">
							<el-icon><ele-Delete /></el-icon>
							删除文件
						</el-button>
						<el-button :type="previewListResource ? 'danger' : 'warning'" plain class="mt10" size="default"
							v-auth="'system:oss:edit'" :icon="previewListResource ? 'ele-View' : 'ele-Hide'"
							@click="handlePreviewListResource(!previewListResource)">
							预览开关 :{{ previewListResource ? "禁用" : "启用" }}
						</el-button>
						<router-link :to="'/ossConfig'" class="link-type mt10" v-auth="'system:oss:edit'">
							<el-button type="info" size="default">
								<el-icon><ele-Operation /></el-icon>
								配置管理
							</el-button>
						</router-link>
					</el-col>
				</el-row>
			</div>
			<el-table :data="state.tableData.data" v-loading="state.tableData.loading" style="width: 100%"
				ref="multipleTableRef" @selection-change="handleSelectionChange">
				<el-table-column type="selection" width="55" align="center" />
				<el-table-column label="存储主键" align="center" prop="ossId" v-if="false" />
				<el-table-column label="文件名" align="center" prop="fileName" width="100" show-overflow-tooltip />
				<el-table-column label="原名" align="center" prop="originalName" width="100" show-overflow-tooltip />
				<el-table-column label="文件后缀" align="center" prop="fileSuffix" width="100" show-overflow-tooltip />
				<el-table-column label="文件展示" align="center" prop="url" width="150" show-overflow-tooltip>
					<template #default="scope">
						<ImagePreview v-if="previewListResource && checkFileSuffix(scope.row.fileSuffix)" :width="100"
							:height="100" :src="scope.row.url" :preview-src-list="[scope.row.url]" />
						<span v-text="scope.row.url"
							v-if="!checkFileSuffix(scope.row.fileSuffix) || !previewListResource" />
					</template>
				</el-table-column>
				<el-table-column label="创建时间" align="center" prop="createTime" width="180">
					<template #default="scope">
						<span>{{ scope.row.createTime }}</span>
					</template>
				</el-table-column>
				<el-table-column label="上传人" align="center" prop="createBy" />
				<el-table-column label="服务商" align="center" prop="service" width="100" />
				<el-table-column label="操作" fixed="right" width="95" show-overflow-tooltip
					v-auths="['system:oss:download', 'system:oss:remove']">
					<template #default="scope">
						<el-button size="small" text type="primary" @click="handleDownload(scope.row)"
							v-auth="'system:oss:download'">下载</el-button>
						<el-button size="small" text type="primary" @click="handleDelete(scope.row)"
							v-auth="'system:oss:remove'">删除</el-button>
					</template>
				</el-table-column>
			</el-table>
			<el-pagination @size-change="onHandleSizeChange" @current-change="onHandleCurrentChange"
				class="mt15 paginationFlex" :pager-count="5" :page-sizes="[10, 20, 30]"
				v-model:current-page="state.tableData.param.pageNum" background
				v-model:page-size="state.tableData.param.pageSize" layout="total, sizes, prev, pager, next, jumper"
				:total="state.tableData.total">
			</el-pagination>
		</el-card>
		<!-- 用户导入对话框 -->
		<el-dialog :title="state.upload.title" v-model="state.upload.open" width="60%" append-to-body>
			<el-upload ref="uploadRef" :limit="1" :headers="state.upload.headers" :accept="state.upload.accept"
				:action="state.upload.url" :disabled="state.upload.isUploading" :on-progress="handleFileUploadProgress"
				:on-success="handleFileSuccess" :auto-upload="false" :multiple="state.upload.multiple" drag>
				<i class="el-icon-upload"></i>
				<el-icon size="128"><ele-UploadFilled /></el-icon>
				<div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
				<template v-slot:tip>
					<div class="el-upload__tip text-center">
						<div class="el-upload__tip">
							<p>
								<span></span>
							</p>
						</div>
						<p><el-icon><ele-WarningFilled /></el-icon><span>仅允许导入{{ state.upload.accept }}格式文件</span></p>
					</div>
				</template>
			</el-upload>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="closeUploadDialog" size="default">取 消</el-button>
					<el-button type="primary" @click="submitFileForm" size="default"
						v-auth="'system:oss:upload'">确认</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts" name="systemOss">
import { ref, reactive, onMounted } from 'vue';
import { ElMessageBox, ElMessage, ElTable, dayjs, UploadInstance } from 'element-plus';
import { ossDownload } from '/@/utils/tool';
import ImagePreview from "/@/components/ImagePreview/index.vue";
import { Session } from '/@/utils/storage';
import { useConfig } from '/@/api/system/config';
import { useOss } from '/@/api/system/oss';

const uploadRef = ref<UploadInstance>()
const previewListResource = ref(true);// 预览开关
const multipleTableRef = ref<InstanceType<typeof ElTable>>()
const multipleSelection = ref<RowOssType[]>([])
const state = reactive({
	tableData: {
		// 表格树数据
		data: [],
		total: 0,
		loading: false,
		param: {
			pageNum: 1,
			pageSize: 10,
			fileName: undefined,
			bucketName: undefined,
			originalName: undefined,
			fileSuffix: undefined,
			createBy: undefined,
			service: undefined
		},
	},
	dateRange: [],
	// 用户导入参数
	upload: {
		// 是否显示弹出层
		open: false,
		// 弹出层标题
		title: "用户导入",
		// 是否禁用上传
		isUploading: false,
		// 文件类型
		accept: ".png, .jpg, .jpeg",
		//是否多选文件上传
		multiple: false,
		// 设置上传的请求头部
		headers: { Authorization: "Bearer " + Session.getToken() },
		// 上传的地址
		url: import.meta.env.VITE_API_URL + "/system/oss/upload",
	},
});

/**
 * 多选
 */
const handleSelectionChange = (val: RowOssType[]) => {
	multipleSelection.value = val
}

/**
 * checkFileSuffix
 * @param fileSuffix
 * @description 检查文件后缀
 */
const checkFileSuffix = (fileSuffix: any) => {
	let arr = ["png", "jpg", "jpeg"];
	return arr.some(type => {
		return fileSuffix.indexOf(type) > -1;
	});
}

/**
 * 初始化表格数据
 * @Api /system/oss/list
 * @returns
 */
const getTableData = async () => {
	state.tableData.loading = true;
	try {
		let param = {};
		if (state.dateRange && state.dateRange.length > 0) {
			param = {
				...state.tableData.param,
				'params[beginCreateTime]': dayjs(state.dateRange[0]).format('YYYY-MM-DD HH:mm:ss'),
				'params[endCreateTime]': dayjs(state.dateRange[1]).format('YYYY-MM-DD HH:mm:ss')
			};
		} else {
			param = { ...state.tableData.param };
		}
		const res = await useOss().listOss(param);
		state.tableData.data = res.rows;
		state.tableData.total = parseInt(res.total);
	} catch (error) {
		Promise.reject(error);
	}
	state.tableData.loading = false;
};

/**
 * 上传文件
 */
const handleFile = () => {
	state.upload.open = true;
	state.upload.title = "文件上传";
	state.upload.accept = ".xls,.xlsx,.md,.txt";
};
/**
 * 上传图片
 */
const handleImage = () => {
	state.upload.open = true;
	state.upload.title = "图片上传";
	state.upload.accept = ".png,.jpg,.jpeg";
};
/**
 * 文件上传处理
 */
const submitFileForm = () => {
	uploadRef.value!.submit();
};
// 文件上传中处理
const handleFileUploadProgress = () => {
	state.upload.isUploading = true;// 上传中，将上传状态设置为true

};
// 文件上传成功处理
const handleFileSuccess = (response: any) => {
	state.upload.isUploading = false;// 上传成功后，将上传状态设置为false
	if (response.code === 200) {
		ElMessage.success(response.msg);
		closeUploadDialog();
		getTableData();
	} else if (response.code === 500) {
		ElMessageBox.alert(
			response.msg,
			{
				dangerouslyUseHTMLString: true,
			}
		)
	} else {
		Promise.reject(response.msg);
		ElMessage.error(response.msg);
	}
};

/**
 * 关闭文件上传弹窗
 */
const closeUploadDialog = () => {
	state.upload.open = false;
	state.upload.isUploading = false;
};

/**
 * 预览开关
 * @param flag 预览开关
 */
const handlePreviewListResource = async (flag: boolean) => {
	try {
		await ElMessageBox.confirm('此操作将关闭预览, 是否继续?', '提示', {
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			type: 'warning'
		}).then(() => {
			useConfig().updateConfigByKey("sys.oss.previewListResource", flag).then((res => {
				if (res.code === 200) {
					ElMessage.success(res.msg);
					previewListResource.value = !flag;
					getTableData();
					previewListResource.value = flag;
				} else {
					ElMessage.error(res.msg);
				}
			}))
		}).catch(() => {
			previewListResource.value = !flag;
		})
	} catch (error) {
		previewListResource.value = !flag;
		ElMessage.error('操作失败,错误未知');
		Promise.reject(error);
	}

};


/**
 * 多选删除
 * */
const handleDeletes = async () => {
	const confirmResult = await ElMessageBox.confirm('此操作将删除选中的文件, 是否继续?', '提示', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		type: 'warning'
	})
	if (confirmResult !== 'confirm') {
		return
	}
	const deletePromises = multipleSelection.value.map((item) => {
		return useOss().delOss(item.ossId)
	})
	try {
		const results = await Promise.all(deletePromises)
		results.forEach((res) => {
			if (res.code === 200) {
				ElMessage.success(res.msg)
			} else {
				ElMessage.error(res.msg)
			}
		})
		getTableData()
	} catch (err) {
		return Promise.reject(err)
	}
};


/**
 * 下载文件
 * @param row 当前行数据
 */
const handleDownload = (row: RowOssType) => {
	ossDownload(row.ossId);
};



/**
 * 删除文件
 * @param row 当前行数据
 */
const handleDelete = async (row: RowOssType) => {
	try {
		const confirmResult = await ElMessageBox.confirm(`此操作将永久删除该文件, 是否继续?`, '提示', {
			confirmButtonText: '删除',
			cancelButtonText: '取消',
			type: 'warning',
		});
		if (confirmResult === 'confirm') {
			const response = await useOss().delOss(row.ossId);
			ElMessage.success(response.msg);
			getTableData();
		} else {
			ElMessage.info('已取消删除');
		}
	} catch (error) {
		Promise.reject(error);
	}
};



/**
 * 重置查询参数
 */
const resetParamData = () => {
	state.dateRange = [];
	state.tableData.param = {
		pageNum: 1,
		pageSize: 10,
		fileName: undefined,
		bucketName: undefined,
		originalName: undefined,
		fileSuffix: undefined,
		createBy: undefined,
		service: undefined
	};
	getTableData();
};

// 分页改变
const onHandleSizeChange = (val: number) => {
	state.tableData.param.pageSize = val;
	getTableData();
};
// 分页改变
const onHandleCurrentChange = (val: number) => {
	state.tableData.param.pageNum = val;
	getTableData();
};

// 页面加载时
onMounted(() => {
	getTableData();
});
</script>
<style lang="scss" scoped>
.mt10 {
	max-width: 140px;
	margin: 10px 0 10px 10px;
}


.el-upload__tip {

	p {
		display: flex;
		align-items: center;

		.el-link {
			font-size: 12px;
			vertical-align: baseline;
		}
	}

	span {
		display: flex;
		align-items: center;
		margin: 0 8px;
	}


}</style>